package gui;
import db.DBManager;
import struct.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
//import java.awt.*;
import javax.swing.event.*;


/**
 * @author Sarah Wegner
 * @author Gabrielle DuBois
 */
public class AddHouseholdGui extends javax.swing.JFrame implements TableModelListener{
    /** Creates new form AddHouseholdGui */
    public AddHouseholdGui() {
        initComponents();
        initFields();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblAddNewHousehold = new javax.swing.JLabel();
        tabbedPane = new javax.swing.JTabbedPane();
        tabAdult = new javax.swing.JScrollPane();
        jAdultTable = new javax.swing.JTable();
        jDependentsTab = new javax.swing.JScrollPane();
        jNewDependentTable = new javax.swing.JTable();
        jScrollPane2 = new javax.swing.JScrollPane();
        jExistDependentTable = new javax.swing.JTable();
        jFamilyTab = new javax.swing.JScrollPane();
        jFamilyInformationTable = new javax.swing.JTable();
        jAddressTab = new javax.swing.JScrollPane();
        jAddressTable = new javax.swing.JTable();
        jContributionsTab = new javax.swing.JScrollPane();
        jContributionTable = new javax.swing.JTable();
        jMinistryInterestTab = new javax.swing.JScrollPane();
        jMinistryInterestTable = new javax.swing.JTable();
        jScrollPane1 = new javax.swing.JScrollPane();
        jMinistryHistoryTable = new javax.swing.JTable();
        jSeparator2 = new javax.swing.JSeparator();
        btSave = new javax.swing.JButton();
        btCancel = new javax.swing.JButton();
        btAddRow = new javax.swing.JButton();
        btRemoveRow = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setName("frameAddNewHousehold"); // NOI18N

        lblAddNewHousehold.setFont(new java.awt.Font("Tahoma", 0, 14));
        lblAddNewHousehold.setText("Add New Household");

        tabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                tabbedPaneStateChanged(evt);
            }
        });

        jAdultTable.setBackground(new java.awt.Color(230, 230, 255));
        jAdultTable.setModel(adultTableModel);
        jAdultTable.setName("addAdultTable"); // NOI18N
        tabAdult.setViewportView(jAdultTable);

        tabbedPane.addTab("Adults", tabAdult);

        jNewDependentTable.setBackground(new java.awt.Color(230, 230, 255));
        jNewDependentTable.setModel(newDependentTableModel);
        jNewDependentTable.setName("addNewDependent"); // NOI18N
        jDependentsTab.setViewportView(jNewDependentTable);

        tabbedPane.addTab("New Dependents", jDependentsTab);

        jExistDependentTable.setBackground(new java.awt.Color(230, 230, 255));
        jExistDependentTable.setModel(existDependentTableModel);
        jExistDependentTable.setName("addExistingDependent"); // NOI18N
        jScrollPane2.setViewportView(jExistDependentTable);

        tabbedPane.addTab("Existing Dependents", jScrollPane2);

        jFamilyInformationTable.setBackground(new java.awt.Color(230, 230, 255));
        jFamilyInformationTable.setModel(familyTableModel);
        jFamilyInformationTable.setName("addFamilyInformation"); // NOI18N
        jFamilyTab.setViewportView(jFamilyInformationTable);

        tabbedPane.addTab("Family Information", jFamilyTab);

        jAddressTable.setBackground(new java.awt.Color(230, 230, 255));
        jAddressTable.setModel(addressTableModel);
        jAddressTable.setName("addAddresses"); // NOI18N
        jAddressTab.setViewportView(jAddressTable);

        tabbedPane.addTab("Addresses", jAddressTab);

        jContributionTable.setBackground(new java.awt.Color(230, 230, 255));
        jContributionTable.setModel(contributionTableModel);
        jContributionTable.setName("addContributions"); // NOI18N
        jContributionsTab.setViewportView(jContributionTable);

        tabbedPane.addTab("Contributions", jContributionsTab);

        jMinistryInterestTable.setBackground(new java.awt.Color(230, 230, 255));
        jMinistryInterestTable.setModel(ministryInterestTableModel);
        jMinistryInterestTable.setName("addInterest"); // NOI18N
        jMinistryInterestTab.setViewportView(jMinistryInterestTable);

        tabbedPane.addTab("Ministry Interest", jMinistryInterestTab);

        jMinistryHistoryTable.setBackground(new java.awt.Color(230, 230, 255));
        jMinistryHistoryTable.setModel(ministryHistoryTableModel);
        jMinistryHistoryTable.setName("addHistory"); // NOI18N
        jScrollPane1.setViewportView(jMinistryHistoryTable);

        tabbedPane.addTab("Ministry History", jScrollPane1);

        jSeparator2.setForeground(new java.awt.Color(0, 153, 0));
        jSeparator2.setMaximumSize(new java.awt.Dimension(2147483647, 2147483647));

        btSave.setText("Save");
        btSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btSaveActionPerformed(evt);
            }
        });

        btCancel.setText("Cancel");
        btCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btCancelActionPerformed(evt);
            }
        });

        btAddRow.setText("Add Row");
        btAddRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btAddRowActionPerformed(evt);
            }
        });

        btRemoveRow.setText("Delete Row");
        btRemoveRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btRemoveRowActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 1164, Short.MAX_VALUE)
                    .addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 1164, Short.MAX_VALUE)
                    .addComponent(lblAddNewHousehold)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(btRemoveRow)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btAddRow)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btCancel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btSave, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblAddNewHousehold)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(23, 23, 23)
                .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 464, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btSave)
                    .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btAddRow)
                    .addComponent(btRemoveRow))
                .addContainerGap())
        );

        tabbedPane.getAccessibleContext().setAccessibleName("AddHouseholdTab");

        getAccessibleContext().setAccessibleName("frame");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btAddRowActionPerformed
        //get index of selected tab
        int tabIndex = tabbedPane.getSelectedIndex();
        //Only 2 adults are allowed per family
        //Disable add row button if adults > 2
        if(tabIndex == 0){
            int countAdult = adultTableModel.getRowCount();
            if(countAdult < 2){
                adultTableModel.addRow(new Object[] {"","","","","","","","","",""});

                //request focus to toggle the add/edit buttons
                jAdultTable.requestFocus();
                btAddRow.setToolTipText("A family can only have two adult records.");
            }//else
            else{
                JOptionPane.showMessageDialog(null,
                    "A family can only have two adult records.", "Add Adult",
                    JOptionPane.WARNING_MESSAGE);
            }
        }//tabIndex = 0
        else if(tabIndex == 1){
            newDependentTableModel.addRow(new Object[] {"","","","","","",""});
            jNewDependentTable.requestFocus();
            btAddRow.setToolTipText(null);
        }//tabIndex = 1
        else if(tabIndex == 2){
            existDependentTableModel.addRow(new Object[] {"","","","","","","",""});
            jExistDependentTable.requestFocus();
            btAddRow.setToolTipText(null);
        }//tabIndex = 1
        else if(tabIndex == 3){
           JOptionPane.showMessageDialog(null,
                    "A family only needs one family information record.", "Add Adult",
                    JOptionPane.WARNING_MESSAGE);
        }//tabIndex = 2
        else if(tabIndex == 4){
            addressTableModel.addRow(new Object[] {"","","","","",false,""});
        }//tabIndex = 3
        else if(tabIndex == 5){
            contributionTableModel.addRow(new Object[] {"","","",""});
        }//tabIndex = 4
        else if(tabIndex == 6){
            ministryInterestTableModel.addRow(new Object[] {"",""});
        }//tabIndex = 5
        else if(tabIndex == 7){
            ministryHistoryTableModel.addRow(new Object[] {"",""});
        }//tabIndex = 6
    }//GEN-LAST:event_btAddRowActionPerformed

    private void btCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btCancelActionPerformed
        int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                "you would like to close "+ "\n"+ "this window without saving?",
                "Cancel", JOptionPane.YES_NO_OPTION);
        if (answer == JOptionPane.YES_OPTION) {
            // User clicked YES.
            this.dispose();
        } //else if (answer == JOptionPane.NO_OPTION)
         // User clicked NO. Do nothing.
    }//GEN-LAST:event_btCancelActionPerformed

    private void btSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btSaveActionPerformed

        //Stop Cell editing on all Tabs
        stopCellEditing(jAdultTable);
        stopCellEditing(jNewDependentTable);
        stopCellEditing(jExistDependentTable);
        stopCellEditing(jFamilyInformationTable);
        stopCellEditing(jAddressTable);
        stopCellEditing(jContributionTable);
        stopCellEditing(jMinistryInterestTable);
        stopCellEditing(jMinistryHistoryTable);

        //1. Check for required Fields in all Tabs
        String requiredFields = verifyAllRequiredFields();
        //2. Check for duplicate rows in all Tabs
        String dupTabs = verifyDuplicateRows();
        //3. Check for proper date format in all Tabs
        String dateFields = verifyDateFields();
        //4. Check for proper phone format in all Tabs
        String phoneFields = verifyPhoneFields();
        //5. Check for proper state format
        boolean stateFields = verifyStateFields();
        //6. Check for proper zipcode format
        boolean zipFields = verifyZipFields();
        //7. Check for proper money formats
        boolean moneyFields = verifyMoneyFormat();

        if(!requiredFields.equals("")){
            JOptionPane.showMessageDialog(null, "Please complete the "
                    + "required fields for the following tabs: "
                    + "\n" + requiredFields + "\n\n" +
                    "Note: If a row is empty and is not needed in a particular table, delete"
                    + " the row, then click the 'Save' button. All required"
                    + " fields are marked with a '*'.",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!dupTabs.equals(""))
        {
            JOptionPane.showMessageDialog(null, "The following tabs"
                    + " have duplicate rows: "
                    + "\n" + dupTabs + "\n" + "Please remove the duplicate rows before continuing.",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!dateFields.equals(""))
        {
            JOptionPane.showMessageDialog(null, "The Tabs listed below have dates "
                    + "in incorrect format. Please use MM/DD/YYYY." + "\n" +"Ex: 01/07/1988"
                    + "\n" + dateFields, "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!phoneFields.equals("")){
            JOptionPane.showMessageDialog(null, "The Tabs listed below have phone numbers "
                    + "in incorrect format. Please use (XXX)XXX-XXXX." + "\n" +"Ex: (920)555-5491"
                    + "\n" + phoneFields, "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!stateFields){
            JOptionPane.showMessageDialog(null, "The Address Tab has a 'State' field "
                    + "in incorrect format. Please use XX." + "\n" +"Ex: WI",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!zipFields){
            JOptionPane.showMessageDialog(null, "The Address Tab has a 'Zipcode' field "
                    + "in incorrect format. Please use the 5 or 9 digit format."
                    + "\n" +"Ex: 54952 or 54952-1234",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!moneyFields){
            JOptionPane.showMessageDialog(null, "The Contribution Tab has a money field "
                    + "in incorrect format. Please use the following format, 'XX.XX'."
                    + "\n" +"Ex: 1.00 or 120.25",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else{
            save();
        }//else


    }//GEN-LAST:event_btSaveActionPerformed

    private void btRemoveRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btRemoveRowActionPerformed
        //Remove row in table if the user does not find it necessary
        //get index of selected tab
        int tabIndex = tabbedPane.getSelectedIndex();
        if(tabIndex == 0){
            //stop cell editing
            stopCellEditing(jAdultTable);

            //save row count
            int adultRowCount = jAdultTable.getRowCount();

            //confirm delete of row.
            if(adultRowCount > 0 && adultRowCount != 1){
                int row = jAdultTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        adultTableModel.removeRow(row);
                        //set focus to the adult table to toggle buttons.
                        jAdultTable.requestFocus();
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "You must have at least one adult per family.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 0
        else if(tabIndex == 1){
            //stop cell editing
            stopCellEditing(jNewDependentTable);

            //save row count
            int depRowCount = jNewDependentTable.getRowCount();
            //confirm delete of row.
            if(depRowCount > 0){
                int row = jNewDependentTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        newDependentTableModel.removeRow(row);
                        //set focus to the dependent table to toggle buttons.
                        jNewDependentTable.requestFocus();
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else

        }//tabIndex = 1
        else if(tabIndex == 2){
            //stop cell editing
            stopCellEditing(jExistDependentTable);

            //Save row count
            int depRowCount = jExistDependentTable.getRowCount();

            //confirm delete of row.
            if(depRowCount > 0){
                int row = jExistDependentTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        existDependentTableModel.removeRow(row);
                        //set focus to the dependent table to toggle buttons.
                        jExistDependentTable.requestFocus();
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 2
        else if(tabIndex == 3){
            //do nothing You cannot delete family row
            JOptionPane.showMessageDialog(null,
                    "A family must have family information.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
        }//tabIndex = 3
        else if(tabIndex == 4){
            //stop cell editing
            stopCellEditing(jAddressTable);

            //Save row count
            int addressRowCount = jAddressTable.getRowCount();

            //confirm delete of row.
            if(addressRowCount > 0 && addressRowCount != 1){
                int row = jAddressTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        addressTableModel.removeRow(row);
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "A family must have at least one address.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 4
        else if(tabIndex == 5){
            //stop cell editing
            stopCellEditing(jContributionTable);

            //Save Row count
            int contributionRowCount = jContributionTable.getRowCount();

            //confirm delete of row.
            if(contributionRowCount > 0){
                int row = jContributionTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        contributionTableModel.removeRow(row);
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 5
        else if(tabIndex == 6){
            //stop cell editing
            stopCellEditing(jMinistryInterestTable);

            //Save Row Count
            int interestRowCount = jMinistryInterestTable.getRowCount();

            //confirm delete of row.
            if(interestRowCount > 0){
                int row = jMinistryInterestTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        ministryInterestTableModel.removeRow(row);
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 6
        else if(tabIndex == 7){
            //stop cell editing
            stopCellEditing(jMinistryHistoryTable);

            //Save Row Count
            int historyRowCount = jMinistryHistoryTable.getRowCount();

            //confirm delete of row.
            if(historyRowCount > 0){
                int row = jMinistryHistoryTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        ministryHistoryTableModel.removeRow(row);
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 7
    }//GEN-LAST:event_btRemoveRowActionPerformed
    
    private void jExistDependentTableFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jExistDependentTableFocusGained
        //set buttons on focus gained of Exist Dependent Tab
        if(existDependentTableModel.getRowCount() <= 0){
            btRemoveRow.setEnabled(false);
            btAddRow.setEnabled(true);
        }//if
        else if(existDependentTableModel.getRowCount() > 0){
            btRemoveRow.setEnabled(true);
            btAddRow.setEnabled(true);
        }//else if
}//GEN-LAST:event_jExistDependentTableFocusGained

    private void jAddressTableFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jAddressTableFocusGainedFocusGained
        //set buttons on focus gained of Addresses Tab
        if(addressTableModel.getRowCount() <= 0){
            btRemoveRow.setEnabled(false);
            btAddRow.setEnabled(true);
        }//if
        else if(addressTableModel.getRowCount() > 0){
            btRemoveRow.setEnabled(true);
            btAddRow.setEnabled(true);
        }//else if
}//GEN-LAST:event_jAddressTableFocusGainedFocusGained

    private void jContributionTableFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jContributionTableFocusGained
        //set buttons on focus gained of Addresses Tab
        if(contributionTableModel.getRowCount() <= 0){
            btRemoveRow.setEnabled(false);
            btAddRow.setEnabled(true);
        }//if
        else if(contributionTableModel.getRowCount() > 0){
            btRemoveRow.setEnabled(true);
            btAddRow.setEnabled(true);
        }//else if
}//GEN-LAST:event_jContributionTableFocusGained

    private void jMinistryInterestTableFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jMinistryInterestTableFocusGained
        //set buttons on focus gained of Addresses Tab
        if(ministryInterestTableModel.getRowCount() <= 0){
            btRemoveRow.setEnabled(false);
            btAddRow.setEnabled(true);
        }//if
        else if(ministryInterestTableModel.getRowCount() > 0){
            btRemoveRow.setEnabled(true);
            btAddRow.setEnabled(true);
        }//else if
}//GEN-LAST:event_jMinistryInterestTableFocusGained

    private void jMinistryHistoryTableFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jMinistryHistoryTableFocusGained
        //set buttons on focus gained of Addresses Tab
        if(ministryHistoryTableModel.getRowCount() <= 0){
            btRemoveRow.setEnabled(false);
            btAddRow.setEnabled(true);
        }//if
        else if(ministryHistoryTableModel.getRowCount() > 0){
            btRemoveRow.setEnabled(true);
            btAddRow.setEnabled(true);
        }//else if
}//GEN-LAST:event_jMinistryHistoryTableFocusGained
    
    private void tabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabbedPaneStateChanged
        //Stop Cell editing on all Tabs
        stopCellEditing(jAdultTable);
        stopCellEditing(jNewDependentTable);
        stopCellEditing(jExistDependentTable);
        stopCellEditing(jFamilyInformationTable);
        stopCellEditing(jAddressTable);
        stopCellEditing(jContributionTable);
        stopCellEditing(jMinistryInterestTable);
        stopCellEditing(jMinistryHistoryTable);

        int tabIndex = tabbedPane.getSelectedIndex();
        //Set the "Head of House" column based on adult input.
        if(tabIndex == 3){
            //Get List of Adults
            ArrayList<String> headHouseList = new ArrayList();
            for(int i = 0; i < adultTableModel.getRowCount(); i++ ){
                if(adultTableModel.getValueAt(i, 0)!= null){
                    headHouseList.add(adultTableModel.getValueAt(i, 0).toString());
                }//if
            }//for

            //copy adult arraylist to the array, since combo box editor calls for an array
            String[] headHouse = new String[headHouseList.size()+1];
            headHouse[0] = "";
            for(int i = 0; i < headHouseList.size(); i++){
                headHouse[i+1] = headHouseList.get(i);
            }//for

            //set combo box
            TableColumn colHeadHouse = jFamilyInformationTable.getColumnModel().getColumn(2);
            colHeadHouse.setCellEditor(new MyComboBoxEditor(headHouse));
            colHeadHouse.setCellRenderer(new MyComboBoxRenderer(headHouse));
            jFamilyInformationTable.setRowHeight(20);

            //Set Focus to First Cell
            jFamilyInformationTable.changeSelection(0, 0, false, false);
            jFamilyInformationTable.requestFocus();
            stopCellEditing(jFamilyInformationTable);
        }//if
    }//GEN-LAST:event_tabbedPaneStateChanged

    /**
     * A method to stop cell editing of a JTable
     * @param JTable - the table to stop the cell editing
     */
    private void stopCellEditing(JTable table){
        if (table.getCellEditor() != null) {
            table.getCellEditor().stopCellEditing();
        }//if
    }//stopCellEditing

    /**
     * Method to Verify State Fields in address
     * @return boolean - true if the Zipcode Fields are valid,
     * false if the Zipcode Fields are invalid.
     */
    private boolean verifyZipFields(){
        int zipCount = 0;
        boolean zip = false;

        //Address Tab
        for(int i = 0; i < addressTableModel.getRowCount(); i++){
            String zipField = (String)addressTableModel.getValueAt(i, 3);
            if(!zipField.equals("")){
                if(zipField.length() > 10){
                    zipCount ++;
                }//if
            }//if
        }//for

        if(zipCount != 0){
            zip = false;
        }
        else{
            zip = true;
        }

        return zip;

    }//verifyStateFields()

    /**
     * Method to Verify State Fields in address
     * @return boolean - true if the State Fields are valid,
     * false if the State Fields are invalid.
     */
    private boolean verifyStateFields(){
        int stateCount = 0;
        boolean state = false;

        //Address Tab
        for(int i = 0; i < addressTableModel.getRowCount(); i++){
            String stateField = (String)addressTableModel.getValueAt(i, 2);
            if(!stateField.equals("")){
                if(stateField.length()!= 2){
                    stateCount ++;
                }//if
            }//if
        }//for

        if(stateCount != 0){
            state = false;
        }
        else{
            state = true;
        }

        return state;

    }//verifyStateFields()

    /**
     * Method to Verify all date fields are in correct format
     *
     * @return String of Tabs that do not have proper
     * date format
     */
    private String verifyPhoneFields(){
        int adultCount = 0;
        int depCount = 0;
        int famCount = 0;
        String phones = "";

        //Adult Tab
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            String phone1 = (String)adultTableModel.getValueAt(i, 6);
            String phone2 = (String)adultTableModel.getValueAt(i, 7);
            //if phones are empty and the row is not deleted
            if(!phone1.equals("") && phone1.length()!=13){
                    adultCount ++;
            }//if
            if(!phone2.equals("") && phone2.length()!=13){
                    adultCount ++;
            }//if
        }//for

        //Dependent
        //if Dependent Rows Exist
        if(newDependentTableModel.getRowCount() > 0){
            for(int i = 0; i < newDependentTableModel.getRowCount(); i++){
                String phone3 = (String)newDependentTableModel.getValueAt(i, 5);
                if(!phone3.equals("")){
                    if(phone3.length()!= 13){
                        depCount ++;
                    }//if
                }//if
            }//for
        }//if-rowCount

        //Family
        for(int i = 0; i < familyTableModel.getRowCount(); i++){
            String phone4 = (String)familyTableModel.getValueAt(i, 1);
            if(!phone4.equals("")){
                if(phone4.length()!= 13){
                    famCount ++;
                }//if
            }//if
        }//for

        if(adultCount != 0){
            phones = phones + "\n" + "Adult Tab";
        }//if
        if(depCount !=0){
            phones = phones + "\n" + "New Dependent Tab";
        }//if
        if(famCount != 0){
            phones = phones + "\n" + "Family Tab";
        }//if

        return phones;

    }//verifyPhoneFields();

    /**
     * Method to Verify all date fields are in correct format
     *
     * @return String of Tabs that do not have proper
     * date format
     */
    private String verifyDateFields(){
        int adultCount = 0;
        int depCount = 0;
        int historyCount = 0;
        String dates = "";

        //Adult Tab
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            //Field is required, don't allow empty string.
            if(!Validator.isDate((String)adultTableModel.getValueAt(i, 2))
                    && !(adultTableModel.getValueAt(i, 2).toString().trim()).equals("")){
                adultCount++;
            }//if
            //Field is not required, allow empty string.
            if(!Validator.isDate((String)adultTableModel.getValueAt(i, 3))
                    && !(adultTableModel.getValueAt(i, 3).toString().trim()).equals("")){
                adultCount++;
            }//if
        }//for

        //Dependent
        for(int i = 0; i < newDependentTableModel.getRowCount(); i++){
            //Check each row for column 2 (primary keys) if row is not deleted
            if(!Validator.isDate((String)newDependentTableModel.getValueAt(i,2))
                    && !(newDependentTableModel.getValueAt(i,2).toString().trim()).equals(""))
            {
                depCount ++;
            }//if
        }//for

        //Ministry History
        //if ministry history rows exist
        if(ministryHistoryTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryHistoryTableModel.getRowCount(); i++){
                //Check each row for column 1,2 (primary keys)
                if(!Validator.isDate(((String)ministryHistoryTableModel.getValueAt(i,1)))
                        && !((String)ministryHistoryTableModel.getValueAt(i,1)).equals(""))
                {
                    historyCount ++;
                }//if
            }//for
        }//if-rowcount

        if(adultCount != 0){
            dates = dates + "\n" + "Adult Tab";
        }//if
        if(depCount !=0){
            dates = dates + "\n" + "New Dependent Tab";
        }//if
        if(historyCount != 0){
            dates = dates + "\n" + "Ministry History Tab";
        }//if

        return dates;

    }//verifyDateFields();

   /**
    * Check for duplicates in each tab
    * @return boolean false if there are duplicates; true if there is no duplicates
    * @param TableModel tableModel is the table model of the tab you want to check duplicates of
    * @param Int primaryKey is the size of the primary key of the table
    */
    private boolean checkDups(AddTableModel tableModel, int primaryKey){
        int rowCount = tableModel.getRowCount();

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < rowCount; i++){
            int equalColumnCount = 0;

            //check first three columns
            for(int k = 0; k <= rowCount && k != i; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(tableModel.getValueAt(i, j).equals(tableModel.getValueAt(k, j))){
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }

                equalColumnCount = 0;
            }//for-k

        }//for-i
        return noDuplicates;
    }

    /**
     * Check for duplicates between Adults & New Dependents tab
     */
    private boolean adultAndNewDepDuplicates(){

        int adultRowCount = adultTableModel.getRowCount();
        int depRowCount = newDependentTableModel.getRowCount();
        int primaryKey = 3;

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < adultRowCount; i++){
            int equalColumnCount = 0;

            //check first three columns
            for(int k = 0; k < depRowCount; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(adultTableModel.getValueAt(i, j).equals(newDependentTableModel.getValueAt(k, j))){
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }

                equalColumnCount = 0;
            }//for-k

        }//for-i
        return noDuplicates;
    }//adultAndNewDepDuplicates

    /**
     * Check for duplicates between Adults & Existing Dependents tab
     */
    private boolean adultAndExistingDepDuplicates(){

        int adultRowCount = adultTableModel.getRowCount();
        int depRowCount = existDependentTableModel.getRowCount();
        int primaryKey = 3;

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < adultRowCount; i++){
            int equalColumnCount = 0;

            //check first three columns
            for(int k = 0; k < depRowCount; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(adultTableModel.getValueAt(i, j).equals(existDependentTableModel.getValueAt(k, j+1))){
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }

                equalColumnCount = 0;
            }//for-k

        }//for-i
        return noDuplicates;
    }//adultAndExistDepDuplicates

    /**
     * Check for duplicates between Adults & Existing Dependents tab
     */
    private boolean newDepAndExistingDepDuplicates(){

        int newDepRowCount = newDependentTableModel.getRowCount();
        int depRowCount = existDependentTableModel.getRowCount();
        int primaryKey = 3;

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < newDepRowCount; i++){
            int equalColumnCount = 0;

            //check first three columns
            for(int k = 0; k < depRowCount; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(newDependentTableModel.getValueAt(i, j).equals(existDependentTableModel.getValueAt(k, j+1))){
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }

                equalColumnCount = 0;
            }//for-k

        }//for-i
        return noDuplicates;
    }//newDepAndExistDepDuplicates

    /**
     * Method to verify each tab does not have duplicate rows
     * @return String of Tabs that have duplicate rows
     */
    private String verifyDuplicateRows(){
        //do not need to check duplicates in family because
        //you can only add one row.
        boolean adultDups = checkDups(adultTableModel,3);
        boolean depDups = checkDups(newDependentTableModel,3);
        boolean existDepDups = checkDups(existDependentTableModel,1);
        boolean addDups = checkDups(addressTableModel,4);
        boolean contrDups = checkDups(contributionTableModel,1);
        boolean interestDups = checkDups(ministryInterestTableModel,1);
        boolean historyDups = checkDups(ministryHistoryTableModel,2);
        boolean adultAndNewDep = adultAndNewDepDuplicates();
        boolean adultAndExistDep = adultAndExistingDepDuplicates();
        boolean newAndExistDep = newDepAndExistingDepDuplicates();
        
        String dupTabs = "";
        
        if(adultDups && depDups && addDups && contrDups
                && interestDups && historyDups && adultAndNewDep
                && adultAndExistDep && newAndExistDep){
            //do nothing
        }//if
        else{
            if(!adultDups){
                dupTabs = dupTabs + "\n" + "Adult Tab:"
                        + " Unique fields are the First Name, "
                        + "Last Name, and Date of Birth.";
            }//if
            if(!depDups){
                dupTabs = dupTabs + "\n" + "New Dependent Tab:"
                        + " Unique fields are the First Name, "
                        + "Last Name, and Date of Birth.";
            }//if
            if(!existDepDups){
                dupTabs = dupTabs + "\n" + "Existing Dependent Tab:"
                        + " Unique fields are the First Name, "
                        + "Last Name, and Date of Birth.";
            }//if
            if(!addDups){
                dupTabs = dupTabs + "\n" + "Address Tab:"
                        + " Unique fields are the Street, "
                        + "City, State, and Zipcode.";
            }//if
            if(!contrDups){
                dupTabs = dupTabs + "\n" + "Contribution Tab:"
                        + " Unique field is the Year.";
            }//if
            if(!interestDups){
                dupTabs = dupTabs + "\n" + "Ministry Interest Tab:"
                        + " Unique field is the Ministry Name.";
            }//if
            if(!historyDups){
                dupTabs = dupTabs + "\n" + "Ministry History Tab:"
                        + " Unique fields are the Ministry Name and Date.";
            }//if
            if(!adultAndNewDep){
                dupTabs = dupTabs + "\n" + "Rows in the Adult and New Dependent Tabs share the same unique fields.";
            }
            if(!adultAndExistDep){
                dupTabs = dupTabs + "\n" + "Rows in the Adult and Existing Dependent Tabs share the same unique fields.";
            }
            if(!newAndExistDep){
                dupTabs = dupTabs + "\n" + "Rows in the New Dependent and Existing Dependent Tabs share the same unique fields.";
            }
        }//else
        
        return dupTabs;
    }//verifyDuplicateRows

    /**
     * Method to verify all required fields are complete
     * 
     * @return String of Tabs that do not have completed required fields
     */
    private String verifyAllRequiredFields(){
        //Check Required fields of each tab then clear for another entry
        String nullTabs = "";

        if(!checkAdultTab()){
            nullTabs = nullTabs + "\n" + "Adult Tab";
        }//if
        if(!checkDepTab()){
            nullTabs = nullTabs + "\n" + "New Dependent Tab";
        }//if
        if(!checkExistDepTab()){
            nullTabs = nullTabs + "\n" + "Existing Dependent Tab";
        }
        if(!checkFamTab()){
            nullTabs = nullTabs + "\n" + "Family Tab";
        }//if
        if(!checkAddTab()){
            nullTabs = nullTabs + "\n" + "Address Tab";
        }//if
        if(!checkMoneyTab()){
            nullTabs = nullTabs + "\n" + "Contributions Tab";
        }//if
        if(!checkInterestTab()){
            nullTabs = nullTabs + "\n" + "Ministry Interest Tab";
        }//if
        if(!checkHistoryTab()){
            nullTabs = nullTabs + "\n" + "Ministry History Tab";
        }//if
        
        return nullTabs;
    }//verifyAllRequiredFields

    /**
     * Checks the Adult Tab if all
     * required fields are complete
     */
    private boolean checkAdultTab(){
        boolean adultSave = false;
        int nullCount = 0;
        //check adult
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            //Check each row for column 1,2,3 (primary keys)
            if(adultTableModel.getValueAt(i,0).equals("")
                    | adultTableModel.getValueAt(i,1).equals("")
                    | adultTableModel.getValueAt(i,2).equals(""))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            adultSave = false;
        }//if
        else{
            adultSave = true;
        }//else
        return adultSave;

    }//checkAdultTab()

    /**
     * Checks the Dependent Tab if all
     * required fields are complete
     */
    private boolean checkExistDepTab(){
        boolean depSave = false;
        int nullCount = 0;
        //check Dependent rows, if they exist
        if(existDependentTableModel.getRowCount() > 0){
            for(int i = 0; i < existDependentTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(existDependentTableModel.getValueAt(i,0).equals("")
                        | existDependentTableModel.getValueAt(i,1).equals("")
                        | existDependentTableModel.getValueAt(i,2).equals(""))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            depSave = false;
        }//if
        else{
            depSave = true;
        }//else
        return depSave;
    }//checkDepTab()
    /**
     * Checks the Dependent Tab if all
     * required fields are complete
     */
    private boolean checkDepTab(){
        boolean depSave = false;
        int nullCount = 0;
        //check Dependent rows, if they exist
        if(newDependentTableModel.getRowCount() > 0){
            for(int i = 0; i < newDependentTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(newDependentTableModel.getValueAt(i,0).equals("")
                        | newDependentTableModel.getValueAt(i,1).equals("")
                        | newDependentTableModel.getValueAt(i,2).equals(""))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            depSave = false;
        }//if
        else{
            depSave = true;
        }//else
        return depSave;
    }//checkDepTab()

    /**
     * Checks the Family Tab if all
     * required fields are complete
     */
    private boolean checkFamTab(){
        boolean famSave = false;
        int nullCount = 0;
        //check adult
        for(int i = 0; i < familyTableModel.getRowCount(); i++){
            //Check each row for required fields
            if(familyTableModel.getValueAt(i,0).equals("")
                    | familyTableModel.getValueAt(i,1).equals("")
                    | familyTableModel.getValueAt(i,2).equals("")
                    | familyTableModel.getValueAt(i, 5).equals(""))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            famSave = false;
        }//if
        else{
            famSave = true;
        }//else
        return famSave;
        
    }//checkFamilyTab()

    /**
     * Checks the Address Tab if all
     * required fields are complete
     */
    private boolean checkAddTab(){
        boolean addressSave = false;
        int nullCount = 0;
        //check address
        for(int i = 0; i < addressTableModel.getRowCount(); i++){
            //Check each row for required fields
            if(addressTableModel.getValueAt(i,0).equals("")
                    | addressTableModel.getValueAt(i,1).equals("")
                    | addressTableModel.getValueAt(i,2).equals("")
                    | addressTableModel.getValueAt(i,3).equals(""))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            addressSave = false;
        }//if
        else{
            addressSave = true;
        }//else
        return addressSave;
        
    }//checkAddTab()

    /**
     * Checks the Contribution Tab if all
     * required fields are complete
     */
    private boolean checkMoneyTab(){
        boolean moneySave = false;
        int nullCount = 0;
        //check Money, if rows exist
        if(contributionTableModel.getRowCount() > 0){
            for(int i = 0; i < contributionTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(contributionTableModel.getValueAt(i,0).equals(""))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            moneySave = false;
        }//if
        else{
            moneySave = true;
        }//else
        return moneySave;
    }//checkMoneyTab()

        /**
     * Verify money format in the
     * Year to date and pledged fields to be sure they
     * are of double format
     */
    private boolean verifyMoneyFormat(){
        boolean moneySave = false;
        int formatCount = 0;
        //check Money, if rows exist
        if(contributionTableModel.getRowCount() > 0){
            for(int i = 0; i < contributionTableModel.getRowCount(); i++){
                //Check each row for money fields
                if(!Validator.isMoney((String)contributionTableModel.getValueAt(i,1)))
                {
                    formatCount ++;
                }//if
                if(!Validator.isMoney((String)contributionTableModel.getValueAt(i,2)))
                {
                    formatCount ++;
                }//if
            }//for
        }//if

        if(formatCount != 0){
            moneySave = false;
        }//if
        else{
            moneySave = true;
        }//else
        return moneySave;
    }//verifyMoneyFormat()

    /**
     * Checks the Interest Tab if all
     * required fields are complete
     */
    private boolean checkInterestTab(){
        boolean interestSave = false;
        int nullCount = 0;
        //check Interest, if rows exist
        if(ministryInterestTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryInterestTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(ministryInterestTableModel.getValueAt(i,0).equals(""))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            interestSave = false;
        }//if
        else{
            interestSave = true;
        }//else
        return interestSave;
    }//checkInterestTab()

    /**
     * Checks the History Tab if all
     * required fields are complete
     */
    private boolean checkHistoryTab(){
        boolean historySave = false;
        int nullCount = 0;
        //check Money, if rows exist
        if(ministryHistoryTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryHistoryTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(ministryHistoryTableModel.getValueAt(i,0).equals("")
                        |ministryHistoryTableModel.getValueAt(i,1).equals(""))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            historySave = false;
        }//if
        else{
            historySave = true;
        }//else
        return historySave;
    }//checkHistoryTab()

    /**
     * Saves new household to database
     */
    private void save(){
        boolean saveSuccessful = false;
        boolean addHousehold = false;
        String rowsWithDups = "";
        boolean dupsExist = false;

        //Save new household to DB
        //get family key
        String[] familyKey = {(String)familyTableModel.getValueAt(0, 0),
                              (String)familyTableModel.getValueAt(0, 1)};
        try {
            DBManager dbManager = new DBManager();
            /*Get ADULTS*/
            int rowCount = adultTableModel.getRowCount();
            Adult[] adultArray = new Adult[rowCount];
            Adult adult;
            for(int i = 0; i < rowCount; i++){
               adult = new
                        Adult((String)adultTableModel.getValueAt(i, 0),
                                 (String)adultTableModel.getValueAt(i, 1),
                                 (String)adultTableModel.getValueAt(i, 2),
                                 (String)adultTableModel.getValueAt(i, 3),
                                 (String)adultTableModel.getValueAt(i, 4),
                                 (String)adultTableModel.getValueAt(i, 5),
                                 (String)adultTableModel.getValueAt(i, 6),
                                 (String)adultTableModel.getValueAt(i, 7),
                                 (String)adultTableModel.getValueAt(i, 8),
                                 (String)adultTableModel.getValueAt(i, 9));

               String[] adultKey = {(String)adultTableModel.getValueAt(i, 0),
                                    (String)adultTableModel.getValueAt(i, 1),
                                    (String)adultTableModel.getValueAt(i, 2)};
               boolean doesExist = dbManager.doesExist("adults", adultKey);
               if(doesExist){
                  dupsExist = true;
                  rowsWithDups = rowsWithDups + "Adult Tab Row: " + (i + 1) + "\n";
               }
               adultArray[i]= adult;
            }//for

            /*Get New DEPENDENTS*/
            int depRowCount = newDependentTableModel.getRowCount();
            Dependent[] depArray = new Dependent[depRowCount];
            Dependent dep;
            for(int i = 0; i < depRowCount; i++){
               dep = new
                        Dependent((String)newDependentTableModel.getValueAt(i, 0),
                                 (String)newDependentTableModel.getValueAt(i, 1),
                                 (String)newDependentTableModel.getValueAt(i, 2),
                                 (String)newDependentTableModel.getValueAt(i, 3),
                                 (String)newDependentTableModel.getValueAt(i, 4),
                                 (String)newDependentTableModel.getValueAt(i, 5),
                                 (String)newDependentTableModel.getValueAt(i, 6));

               String[] depKey = {(String)newDependentTableModel.getValueAt(i, 0),
                                    (String)newDependentTableModel.getValueAt(i, 1),
                                    (String)newDependentTableModel.getValueAt(i, 2)};
               boolean doesExist = dbManager.doesExist("dependents", depKey);
               if(doesExist){
                  dupsExist = true;
                  rowsWithDups = rowsWithDups + "New Dependent Tab Row: " + (i+1) + "\n";
               }
               depArray[i]= dep;
            }//for

            /*Get Existing DEPENDENTS*/
            int exDepRowCount = existDependentTableModel.getRowCount();
            Dependent[] exDepArray = new Dependent[exDepRowCount];
            Dependent exDep;
            for(int i = 0; i < exDepRowCount; i++){
               exDep = new
                        Dependent((String)existDependentTableModel.getValueAt(i, 1),
                                 (String)existDependentTableModel.getValueAt(i, 2),
                                 (String)existDependentTableModel.getValueAt(i, 3),
                                 (String)existDependentTableModel.getValueAt(i, 4),
                                 (String)existDependentTableModel.getValueAt(i, 5),
                                 (String)existDependentTableModel.getValueAt(i, 6),
                                 (String)existDependentTableModel.getValueAt(i, 7));
                exDepArray[i]= exDep;
            }//for

            /*Get FAMILY*/
            Family familyInfo =
                        new Family((String)familyTableModel.getValueAt(0, 0),
                                 (String)familyTableModel.getValueAt(0, 1),
                                 (String)familyTableModel.getValueAt(0, 2),
                                 (Boolean)familyTableModel.getValueAt(0, 3),
                                 (Boolean)familyTableModel.getValueAt(0, 4),
                                 (String)familyTableModel.getValueAt(0, 5),
                                 (String)familyTableModel.getValueAt(0, 6));
            boolean doesExist = dbManager.doesExist("families", familyKey);
            if(doesExist){
                dupsExist = true;
                rowsWithDups = rowsWithDups + "Family Tab Row: " + 1 + "\n";
            }

            /*Get Ministry Info*/
            int histRowCount = ministryHistoryTableModel.getRowCount();
            History[] historyArray = new History[histRowCount];
            History history;
            for(int i = 0; i < histRowCount; i++){
               history = new
                        History((String)ministryHistoryTableModel.getValueAt(i, 0),
                                 (String)ministryHistoryTableModel.getValueAt(i, 1));
               historyArray[i]= history;
            }//for

            int interestRowCount = ministryInterestTableModel.getRowCount();
            Interest[] interestArray = new Interest[interestRowCount];
            Interest interest;
            for(int i = 0; i < interestRowCount; i++){
               interest = new
                        Interest((String)ministryInterestTableModel.getValueAt(i, 0),
                                 (String)ministryInterestTableModel.getValueAt(i, 1));
               interestArray[i]= interest;
            }//for

            /*Get Address*/
            int addRowCount = addressTableModel.getRowCount();
            Address[] addArray = new Address[addRowCount];
            Address address;
            for(int i = 0; i < addRowCount; i++){
               address = new
                        Address((String)addressTableModel.getValueAt(i, 0),
                                 (String)addressTableModel.getValueAt(i, 1),
                                 (String)addressTableModel.getValueAt(i, 2),
                                 (String)addressTableModel.getValueAt(i, 3),
                                 (String)addressTableModel.getValueAt(i, 4),
                                 (Boolean)addressTableModel.getValueAt(i, 5),
                                 (String)addressTableModel.getValueAt(i, 6));

                addArray[i]= address;
            }//for

            /*Get Monies*/
            int moneyRowCount = contributionTableModel.getRowCount();
            Money[] moneyArray = new Money[moneyRowCount];
            Money money;
            for(int i = 0; i < moneyRowCount; i++){
               money = new
                        Money((String)contributionTableModel.getValueAt(i, 0),
                                 Double.parseDouble((String)contributionTableModel.getValueAt(i, 1)),
                                 Double.parseDouble((String)contributionTableModel.getValueAt(i, 2)),
                                 (String)contributionTableModel.getValueAt(i, 3));
                moneyArray[i]= money;
            }//for

            //MUST ADD In The Following Order:
            //1. Add Adults
            //2. Add New Dependents
            //3. Add Existing Dependents
            //4. Add Family (add ministries included)
            //5. Add Addresses/Money

            //dbManager.
            if(dupsExist){
                saveSuccessful = false;
            }//if
            else{
               addHousehold = dbManager.addHousehold(adultArray, depArray,
                                exDepArray, familyInfo, addArray, moneyArray,
                                interestArray, historyArray);

                if(addHousehold){
                    saveSuccessful = true;
                }//if
                else{
                   saveSuccessful = false;
                }
            }//else
        }//try
        catch (Exception ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error with saving to St Patrick database." + "\n" +
                    "Please contact your Database Administrator, a.k.a Thomas Naps, for help."
                    + "\n" + "(Method: save() in AddHouseholdGui.java)",
                    "Database Error", JOptionPane.ERROR_MESSAGE);
            return;
        }//catch

        if(saveSuccessful == true){
            JOptionPane.showMessageDialog(null,"Save successful!", "Save",
                    JOptionPane.INFORMATION_MESSAGE);
            //clear();//Clear all fields and allow for another entry.
            //initFields();
            this.dispose();
            run();
        }//if
        else{//Save was not succesfull, and
            if(addHousehold == false && dupsExist == false){//if addHousehold is false, and saveSuccessful false, and dupsExist false, other undetermined error occurred.
                JOptionPane.showMessageDialog(null, "Sorry, the save was not successful due to an error" + "\n" +
                    "Please contact your Database Administrator, a.k.a Thomas Naps, for help if this persists.",
                    "Database Saving Error", JOptionPane.ERROR_MESSAGE);
            }//if
            else{//addHousehold
                JOptionPane.showMessageDialog(null,"Sorry, the save was not successful." + "\n"
                        + " Entries listed below already exist in the database." +
                        "\n" + rowsWithDups,
                        "Save Error",
                        JOptionPane.WARNING_MESSAGE);
            }//else
        }//else

    }//save()


    /**
     * Clears all values after a save and sets original states
     * of each field
     */
    private void clear(){
        //Clear all fields in AddHousehold
        int adultRowCount = adultTableModel.getRowCount();
        int adultColumnCount = adultTableModel.getColumnCount();
        int dependentRowCount = newDependentTableModel.getRowCount();
        int dependentColumnCount = newDependentTableModel.getColumnCount();

        //Clear all fields in Adult table
        adultTableModel.setRowCount(1);
        for(int j = 0; j < adultColumnCount; j++){
            //Set each row to a null string
            adultTableModel.setValueAt("", 0, j);
        }//Inner-for-j

        //Delete rows in Dependent tables
        newDependentTableModel.setRowCount(0);
        existDependentTableModel.setRowCount(0);

        //Clear Family row (only 1 row @ index 0)
        for(int j = 0; j < familyTableModel.getColumnCount(); j++){
            familyTableModel.setValueAt("", 0, j);
        }//for

        //Clear Address row (only 1 row @ index 0)
        addressTableModel.setRowCount(1);
        for(int j = 0; j < addressTableModel.getColumnCount(); j++){
            addressTableModel.setValueAt("", 0, j);
        }//for

        //Clear Contributions
        contributionTableModel.setRowCount(0);

        //Clear Ministry Interest & History
        ministryInterestTableModel.setRowCount(0);
        ministryHistoryTableModel.setRowCount(0);

        //set selected tab to Adult Tab
        tabbedPane.setSelectedIndex(0);

    }//clear()


    /**
     * Listens for Table Changes on the existingDependent tab
     * to automatically populate the required fields based off the selection.
     * 
     * @param TableModelEvent - the event that causes a change in a table.
     */
    public void tableChanged(TableModelEvent e){
        //int row = e.getFirstRow();
        //int column = e.getColumn();
        AddTableModel model = (AddTableModel)e.getSource();

        if(model == existDependentTableModel){
            if(e.getColumn() == 0){
                String existDepValue = (String)model.getValueAt(e.getLastRow(), 0);
                String[] newDepValue = existDepValue.split(";");
                try{
                    DBManager dbManager = new DBManager();
                    Dependent dependent = (Dependent)dbManager.getIndividual(newDepValue[0], newDepValue[1], newDepValue[2]);
                    Object[] depAttr = dependent.getAttributes();
                    for(int i = 1; i < existDependentTableModel.getColumnCount(); i ++){
                        if(depAttr[i-1]!= null){
                            existDependentTableModel.setValueAt(depAttr[i-1], e.getLastRow(), i);
                        }//if
                    }//for-i
                }//try
                catch(Exception ex){
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                        + "with the St. Patrick's database." +"\n"+
                        "Please contact your Database Administrator,"
                        + " a.k.a Thomas Naps, for help if this persists."
                        +"\n"+ "tableChanged() Method: AddHouseholdGui.java",
                        "Database Save Error", JOptionPane.ERROR_MESSAGE);
                }//catch
            }//if
        }//if

    }//tableChanged(TableModelEvent e)

    /**
     * A method to set the table columns to be not moveable
     * @param table - the table to have fixed columns
     */
    private void dontMoveColumns(JTable table){
       //set Main Table to not be able to move columns
        JTableHeader header = table.getTableHeader();
        header.setReorderingAllowed(false);
   }

    /**
     * A method to initialize all the fields
     * Called within constructor
     */
    private void initFields(){
      
        try{
            DBManager dbManager = new DBManager();
            
            //Get All Dependent Names in Array for Existing Dependent Drop-down
            ArrayList<String> dependentKeys = dbManager.getAllIndividualKeys("dependents");
            String[] dependentNamesArray = new String[dependentKeys.size()+1];
            dependentNamesArray[0] = "";
            for(int n = 0; n < dependentKeys.size(); n++){
                dependentNamesArray[n+1] = dependentKeys.get(n);
            }//for
            
            //set "First Name" column of Existing Dependents Tab to be a drop-down of all dependents
            TableColumn colName = jExistDependentTable.getColumnModel().getColumn(0);
            colName.setCellEditor(new AddComboBoxEditor(dependentNamesArray));
            colName.setCellRenderer(new AddComboBoxRenderer(dependentNamesArray));
            jExistDependentTable.setRowHeight(20);
            existDependentTableModel.addTableModelListener(this);

            //Get Ministry Names
            ArrayList<String> ministryNames = dbManager.getMinistryNames(true);
            String[] ministryNamesArray = new String[ministryNames.size()+1];

            //copy ministry names into string array
            ministryNamesArray[0] = "";
            for(int m = 0; m < ministryNames.size(); m++){
                ministryNamesArray[m+1] = ministryNames.get(m);
            }//for

            //Set "Ministry Name" column to be a drop-down of Ministry Names
            TableColumn colInterest = jMinistryInterestTable.getColumnModel().getColumn(0);
            colInterest.setCellEditor(new AddComboBoxEditor(ministryNamesArray));
            colInterest.setCellRenderer(new AddComboBoxRenderer(ministryNamesArray));
            jMinistryInterestTable.setRowHeight(20);

            TableColumn colHistory = jMinistryHistoryTable.getColumnModel().getColumn(0);
            colHistory.setCellEditor(new AddComboBoxEditor(ministryNamesArray));
            colHistory.setCellRenderer(new AddComboBoxRenderer(ministryNamesArray));
            jMinistryHistoryTable.setRowHeight(20);

            //Set "Religeous Schooling" column
            String[] school = {"", "Religious School", "Day School", "Other"};
            TableColumn colSchool = jNewDependentTable.getColumnModel().getColumn(4);
            colSchool.setCellEditor(new MyComboBoxEditor(school));
            colSchool.setCellRenderer(new MyComboBoxRenderer(school));
            jNewDependentTable.setRowHeight(20);

            //set each table not to have movable columns
            dontMoveColumns(jAdultTable);
            dontMoveColumns(jNewDependentTable);
            dontMoveColumns(jExistDependentTable);
            dontMoveColumns(jFamilyInformationTable);
            dontMoveColumns(jAddressTable);
            dontMoveColumns(jContributionTable);
            dontMoveColumns(jMinistryInterestTable);
            dontMoveColumns(jMinistryHistoryTable);

            //set each tab to have zero rows.
            adultTableModel.setRowCount(1);
            newDependentTableModel.setRowCount(0);
            existDependentTableModel.setRowCount(0);
            familyTableModel.setRowCount(1);
            addressTableModel.setRowCount(1);
            contributionTableModel.setRowCount(0);
            ministryHistoryTableModel.setRowCount(0);
            ministryInterestTableModel.setRowCount(0);

        }//try
        catch(Exception ex){
            ex.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error with St Patrick database." + "\n" +
                    "Please contact your Database Administrator, a.k.a Thomas Naps, for help." +
                    "\n" + "(initFields() Method: AddHouseholdGui.java)",
                    "Database Error", JOptionPane.ERROR_MESSAGE);
        }//Exception
    }//initFields(...)

    /**
    * @param args the command line arguments
    */
    public static void run() {
        new AddHouseholdGui().setVisible(true);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btAddRow;
    private javax.swing.JButton btCancel;
    private javax.swing.JButton btRemoveRow;
    private javax.swing.JButton btSave;
    private javax.swing.JScrollPane jAddressTab;
    private javax.swing.JTable jAddressTable;
    private javax.swing.JTable jAdultTable;
    private javax.swing.JTable jContributionTable;
    private javax.swing.JScrollPane jContributionsTab;
    private javax.swing.JScrollPane jDependentsTab;
    private javax.swing.JTable jExistDependentTable;
    private javax.swing.JTable jFamilyInformationTable;
    private javax.swing.JScrollPane jFamilyTab;
    private javax.swing.JTable jMinistryHistoryTable;
    private javax.swing.JScrollPane jMinistryInterestTab;
    private javax.swing.JTable jMinistryInterestTable;
    private javax.swing.JTable jNewDependentTable;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JLabel lblAddNewHousehold;
    private javax.swing.JScrollPane tabAdult;
    private javax.swing.JTabbedPane tabbedPane;
    // End of variables declaration//GEN-END:variables
    private AddTableModel adultTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"","","","","","","","","",""}
                                    },
                                    new String [] {
                                        "First Name*", "Last Name*", "Birthdate*",
                                        "Date Joined", "Occupation","Employer",
                                        "Work Phone","Personal Phone","E-Mail",
                                        "Notes"
                                    }
                                );
    private AddTableModel newDependentTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"","","","","","",""}
                                    },
                                    new String [] {
                                        "First Name*", "Last Name*", "Birthdate*",
                                        "School", "Religious Schooling",
                                        "Personal Phone","Notes"});
    private AddTableModel existDependentTableModel = new AddTableModel(
                                new Object [][] {
                                    {"","","","","","","",""}
                                },
                                new String [] {
                                    "Dependent","First Name*", "Last Name*", "Birthdate*",
                                    "School", "Religious Schooling",
                                    "Personal Phone","Notes"});

    private AddTableModel familyTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"","","",false,false,"",""}
                                    },
                                    new String [] {
                                        "Family Name*", "Primary Phone*", "Head of House*",
                                        "Send Donation Letter?", "Send Ministry Letter?",
                                        "Salutation*","Notes"});

    private AddTableModel addressTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"","","","","", false,""}
                                    },
                                    new String [] {
                                        "Street*", "City*", "State*",
                                        "Zipcode*", "Municipal",
                                        "Current Mailing Address?","Notes"});

        private AddTableModel contributionTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"","","",""}
                                    },
                                    new String [] {
                                        "Year*", "Pledged Amount", "Year-to-Date",
                                        "Notes"});

        private AddTableModel ministryInterestTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"",""}
                                    },
                                    new String [] {
                                        "Ministry Name*", "Availability"});

        private AddTableModel ministryHistoryTableModel = new AddTableModel(
                                    new Object [][] {
                                        {"",""}
                                    },
                                    new String [] {
                                        "Ministry Name*", "Date*"});
}//AddHouseholdGui.java
